import React, { useEffect, useState, Key, FC } from "react";

import TableRender from "@/biz-components/table-render";

import { xhrPostJson } from "@/services";
import { getPageMeta } from "@/services/request/meta";
import {
  useEventsRegister,
  useInitData,
} from "@/biz-components/hoc-form/with-list/use-events";
import { PageConfig } from "@/components/schema-form-render/meta";
import { SchemaFormSearchContent } from "@/components/schema-form-render/components/schema-form-content";
import { useScemaRender } from "@/biz-components/hoc-form/utils";
import { CreateModalListProps } from "hoc-form";
import { getSubmitFormValues } from "@ey-utils/utils/formily-utils/getSubmitFormValues";
import { DynamicObjectAny } from "@/typings";
import { toArray } from "@/biz-components/_common/util";

export interface CreateListProps extends CreateModalListProps {
  oldValue?: any[];
  defaultValue?: any[];
  rowsRender?: DynamicObjectAny;
  noPagination?: boolean;
  noInit?: boolean;
  allSelect?: boolean;
}

const CheckboxTableForm: FC<CreateListProps> = (props) => {
  const F = React.useRef<any>();
  const dataRef = React.useRef<any>([]);
  const {
    metasConfig,
    pageApi,
    dealMetaBeforeRender,
    events,
    pageCode,
    rowSelection = null,
    rowKey,
    modalCode = "",
    oldValue,
    noQueryKeys = false,
    match,
    extraPrams,
    filedConfig,
    formConfigs,
    operWidth,
    editable = false,
    editableIdKey,
    editableColsMap,
    onEditableRowSave,
    nested = false,
    nestedTableColumns = [],
    nestedTableDataKey = "",
    formatSearchData,
    rowsRender,
    reloadFlag,
    validator,
    defaultValue,
    clearSelectedRowKeys,
    noPagination,
    noInit = false,
      allSelect = false,
  } = props;
  const [remoteMetasConfig, setRemoteMetasConfig] = useState<PageConfig>({
    labelAlign: "right",
    layout: 3,
    pageDatas: [],
  });

  const { form, SchemaFormRender } = useScemaRender(filedConfig, formConfigs);
  F.current = form;

  // 规则类型选项
  const [loading, setLoading] = useState(false);
  const [tData, setData] = useState<any>([]);
  useEffect(() => {
    dataRef.current = tData;
  }, [tData]);

  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);

  const [selectValue, setSelectValue] = useState<any[]>([]);

  const hookMapIns = React.useRef({
    tableButtonsEvents: {},
    buttonsEvents: {
      // 重置
      reset: () => {
        F?.current?.reset();
        loadData({}, 1, 10);
      },
      // 搜索按钮点击事件
      handleSearchClick: () => {
        getSubmitFormValues(F?.current).then(async (values) => {
          await loadData({ ...values }, 1, 10);
        });
      },
    },
  });
  const {
    schema,
    searchButtons,
    tableColumns,
    buttons,
    tableButtons,
    pageConfig,
  } = useInitData(metasConfig, remoteMetasConfig);

  const baseRowSelection = {
    selectedRowKeys,
    onChange: (rowKeys: Key[], selectedRows: any[]) => {
      const dataSource = noPagination ? tData : tData?.content;

      const allDataSourceKey =
        toArray(dataSource).map((item: any) => item[rowKey || "id"]) || [];

      setSelectValue(
        selectedRows
          .concat(
            selectValue.filter((item: any) => {
              return !selectedRows.find(
                (current) => current[rowKey || "id"] === item[rowKey || "id"]
              );
            })
          )
          .filter((val) => val)
      );

      const mapValue = (oldValue || [])
        .map((item: any) => {
          return selectValue.find(
            (current) => current[rowKey || "id"] === item[rowKey || "id"]
          );
        })
        .filter((val: any) => val);

      const changeValue = mapValue
        .filter((item: any) => !allDataSourceKey.includes(item[rowKey || "id"]))
        .concat(
          selectedRows.filter((item) =>
            allDataSourceKey.includes(item[rowKey || "id"])
          )
        );

      setSelectedRowKeys(changeValue.map((item: any) => item[rowKey || "id"]));

      rowSelection?.onChange?.(
        changeValue.map((item: any) => item[rowKey || "id"]),
        changeValue
      );
    },
  };

  // 获取 row配置信息
  const getRowSelectionConfig = () => {
    if (rowSelection) {
      return {
        ...rowSelection,
        ...baseRowSelection,
      };
    }
    return null;
  };
  // 初始化数据
  const loadData = async (queryData: any, pageNo: number, pageSize: number) => {
    if (!pageApi) return;
    setLoading(true);

    const queryKeys = formatSearchData
      ? formatSearchData(queryData)
      : { ...queryData };
    try {
      const searchParams = noPagination
        ? {
            ...queryKeys,
            ...(extraPrams || {}),
            pageCode,
          }
        : {
            queryKeys: {
              ...queryKeys,
              ...(extraPrams || {}),
              pageCode,
            },
            pageNo,
            pageSize,
            // TODO:后台处理额外参数统一放外层
            ...(noQueryKeys ? { ...queryKeys, ...(extraPrams || {}) } : {}),
          };

      const res: any = await xhrPostJson(pageApi, searchParams);
      setData(
        noPagination ? toArray(res?.result) : { ...res?.result, number: pageNo }
      );
      setLoading(false);
      clearSelectedRowKeys && clearSelectedRowKeys();
      if (allSelect) {
        setAllSelect(res?.result);
      }
    } catch (err) {
      setLoading(false);
    }
  };

  const setAllSelect = (result: any) => {
    const content = result?.content ? result.content : result;
    if (content?.length) {
      setSelectedRowKeys(content.map((item: any) => item[rowKey || "id"]));
      setSelectValue(content || []);
      rowSelection?.onChange?.(
          content?.map((item: any) => item[rowKey || "id"]) || [],
          content || []
      );
    }
  };

  // 分页搜索
  const search = (current: number, pageSize: number) => {
    const vs = F.current.values;
    loadData({ ...vs }, current, pageSize).finally(() => {});
  };

  // 搜索缓存逻辑
  const handleSearchData = (dt: any = {}) => {
    const vs = F.current?.values;
    const values = {
      ...dt,
      ...vs,
    };

    loadData({ ...values, ...dt }, 1, 10).finally(() => {});
  };

  // 事件注册
  const { getSearchButtons, getTableTopButton } = useEventsRegister(
    hookMapIns,
    events,
    {
      pageCode,
      callback: (flag: boolean = true) => {
        if (flag) {
          search(1, 10);
        } else {
          search(1, 10);
        }
      },
      tableButtons,
      buttons,
      searchButtons,
      loading,
      setLoading,
      hookMapIns,
      validator,
      match,
      dataRef,
    }
  );
  // 初始化请求页面数据
  const initData = () => {
    handleSearchData();
  };
  useEffect(() => {
    if (extraPrams && Object.keys(extraPrams).length > 0 && !noInit) {
      initData();
      return;
    }
    if (reloadFlag) {
      initData();
      return;
    }
  }, [JSON.stringify(extraPrams), reloadFlag]);
  // 获取 metasConfig
  useEffect(() => {
    if (pageCode) {
      getPageMeta(pageCode || "").then((res: any) => {
        if (res.success) {
          if (dealMetaBeforeRender) {
            dealMetaBeforeRender(res.result);
          }
          setRemoteMetasConfig(res.result);
        }
      });
    }
    if (!noInit) {
      initData();
    }
  }, [pageCode, modalCode]);

  useEffect(() => {
    setSelectedRowKeys(
      defaultValue?.map((item: any) => item[rowKey || "id"]) || []
    );
    setSelectValue(defaultValue || []);
    rowSelection?.onChange?.(
      defaultValue?.map((item: any) => item[rowKey || "id"]) || [],
      defaultValue || []
    );
  }, [defaultValue, rowKey]);

  return (
    <>
      <SchemaFormSearchContent footer={getSearchButtons()}>
        {SchemaFormRender && (
          <SchemaFormRender schema={schema} pageConfig={pageConfig} />
        )}
      </SchemaFormSearchContent>
      <TableRender
        rowKey={rowKey || "id"}
        metas={tableColumns || []}
        rowSelection={getRowSelectionConfig()}
        match={match}
        isRequesting={loading}
        handleSearch={search}
        extraAction={getTableTopButton()}
        operation={false}
        operWidth={operWidth}
        operAuths={tableButtons?.map(() => "")}
        dataSource={noPagination ? tData : []}
        data={tData || []}
        editable={editable}
        editableIdKey={editableIdKey}
        editableColsMap={editableColsMap}
        onEditableRowSave={onEditableRowSave}
        nested={nested}
        nestedTableColumns={nestedTableColumns}
        nestedTableDataKey={nestedTableDataKey}
        rowsRender={rowsRender}
        pagination={!noPagination}
      />
    </>
  );
};

export default CheckboxTableForm;
